const crypto = require('crypto');

module.exports = {
  /**
   * 生成随机数； 参数 n, m 均为可选参数；根据传递的参数不同返回不同的类型的随机数
   *   1. 参数 n, m 均填, 则如果参数 e = true；则生成 [n, m] 之间的随机数[i = true整形]，否则 [n, m)
   *   2. 如果只填写了 n；则表示生成多少位长度的随机数字符串(首位包括 0)
   * @param n     如果单独只填写了该参数则表示只生成 n 位长度的随机数; 否则表示生成的随机数必须大于等于 n
   * @param m     生成的随机数必须小于(或等于由参数 e 决定) m
   * @param opts  { object }
   *    number:     {boolean} 生成的随机数是整形还是小数形, 仅在有 m 参数时有效; true 表示整形
   *    end:        {boolean} 生成的随机数是否包含末尾数字m; 仅在有 m 参数并且 number = true 时有效; true 表示包含
   *    firstZero:  {boolean} 默认为 true; 当生成 n 位长度的随机数时, 首位是否包含 0; 如果为 true 则返回的格式是字符串类型
   */
  random(n, m = void 0, opts) {
    let random = Math.random();
    let o = {}; // 配置
    if (typeof m === 'number') { // 传递了 m 参数
      o = Object.assign({}, opts || {});
      if (o.number === true) {
        if (o.end === true) {
          return parseInt(random * (m - n + 1) + n, 10);
        }
        return parseInt(random * (m - n) + n, 10);
      }
      return random * (m - n) + n;
    }
    // 没有传递 m 参数; 生成 n 位长度的随机数字符串(首位包括 0)
    o = Object.assign({ firstZero: true }, m || {});
    if (o.firstZero === true) {
      random = random.toString();
      return random.substr(random.indexOf('.') + 1, n);
    }
    let max = Math.pow(10, n);
    random = parseInt(random * max, 10);
    if (random < max) { // 生成的随机数前置有0, 重新生成
      return this.random(m, o);
    }
    return random;
  },

  md5(str) {
    return crypto.createHash('md5').update(str).digest('hex');
  },
}
